/*
 * @(#)PatientIdentityService.java
 * Date 2013-09-22
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.registry.service.es;

import java.util.List;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Alternative;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;

import org.elasticsearch.action.bulk.BulkResponse;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

import org.hl7.v3.MCCIIN000002UV01;
import org.hl7.v3.PRPAIN201301UV02;
import org.hl7.v3.PRPAIN201302UV02;
import org.hl7.v3.PRPAIN201304UV02;

import us.hornerscorners.lamppost.exception.ServiceActionException;

import us.hornerscorners.lamppost.hl7v3common.utils.HL7Utils;

import us.hornerscorners.lamppost.ihecommon.service.ElasticSearchSource;


import us.hornerscorners.lamppost.model.common.InstanceIdentifier;

import us.hornerscorners.lamppost.model.patient.PatientIdentity;

import us.hornerscorners.lamppost.registry.constant.QueryField;

import us.hornerscorners.lamppost.registry.service.IPatientIdentityService;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-09-22
 * @author         Jim Horner
 */
@ApplicationScoped
@Alternative
public class PatientIdentityService implements IPatientIdentityService {

    /** Field description */
    @Inject
    private ElasticSearchSource source;

    /**
     * Constructs ...
     *
     */
    public PatientIdentityService() {
        super();
    }

    /**
     * Method description
     *
     *
     * @param identifier
     *
     * @throws ServiceActionException
     */
    @Override
    public void addPatientIdentity(InstanceIdentifier identifier)
            throws ServiceActionException {

        PatientIdentity identity = new PatientIdentity(identifier);

        identity.setEntryURN(HL7Utils.toCXString(identifier));

        if (retrievePatientIdentity(identifier) != null) {

            // TODO handle duplicate
        }

        BulkResponse bulkResponse = this.source.writePersistable(identity);

        if (bulkResponse.hasFailures()) {

            this.source.rollbackTransaction(bulkResponse);
        }
    }

    /**
     * Method description
     *
     *
     * @param body
     *
     * @return
     */
    @Override
    public MCCIIN000002UV01 addPatientIdentity(PRPAIN201301UV02 body) {
        throw new UnsupportedOperationException("Not supported yet.");    // To change body of generated methods, choose Tools | Templates.
    }

    /**
     * Method description
     *
     *
     * @param body
     *
     * @return
     */
    @Override
    public MCCIIN000002UV01 resolvePatientIdentity(PRPAIN201304UV02 body) {
        throw new UnsupportedOperationException("Not supported yet.");    // To change body of generated methods, choose Tools | Templates.
    }

    /**
     * Method description
     *
     *
     *
     * @param id
     * @return
     *
     * @throws ServiceActionException
     */
    @Override
    public PatientIdentity retrievePatientIdentity(InstanceIdentifier id)
            throws ServiceActionException {

        PatientIdentity result = null;

        BoolQueryBuilder query = QueryBuilders.boolQuery();

        query.must(
            QueryBuilders.termQuery(
                QueryField.PatientIdentityUniqueIdRoot.getField(), id.getRoot()));

        if (StringUtils.isNotBlank(id.getExtension())) {

            query.must(
                QueryBuilders.termQuery(
                    QueryField.PatientIdentityUniqueIdExtensions.getField(),
                    id.getExtension()));
        }

        List<PatientIdentity> patientIdentities = this.source.runQuery(query,
                                                      PatientIdentity.class);

        if (patientIdentities.isEmpty() == false) {
            result = patientIdentities.get(0);
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param body
     *
     * @return
     */
    @Override
    public MCCIIN000002UV01 revisePatientIdenity(PRPAIN201302UV02 body) {
        throw new UnsupportedOperationException("Not supported yet.");    // To change body of generated methods, choose Tools | Templates.
    }
}
